package com.ptone.messagecenter.common.utils;

import com.ptone.messagecenter.common.base.Common;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 参数非空验证
 *
 * @Author Yuanhk
 * @Date 2020/10/27 15:56
 */
public class VerificationUtil {


    /**
     * 检查obj是否为空
     *
     * @param str
     * @return
     */
    public static Boolean objectIsEmpty(Object str) {
        return Optional.ofNullable(str)
                .map(Object::toString)
                .map(String::isEmpty)
                .orElse(true);
    }

    /**
     * 根据属性名反射取值
     *
     * @param object
     * @param fieldName
     * @return
     */
    public static Object getValue(Object object, String fieldName) {
        String methodName = "get" + Common.upperCase(fieldName);
        try {
            Method method = object.getClass().getMethod(methodName);
            method.setAccessible(true);
            return method.invoke(object);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return null;
    }


    private static List<String> getMapBlanks(Map<String, Object> map, String[] filedNames) {
        return Arrays.stream(filedNames)
                .filter(f -> Common.isBlank(map.get(f)))
                .collect(Collectors.toList());
    }

    /**
     * 检查page
     *
     * @param object
     * @param filedNames
     * @throws BindException
     */
    public static void checkPage(Object object, String... filedNames) throws BindException {
        checkNull(object, Common.concat(filedNames, new String[]{"currentPage", "pageSize"}));
    }

    /**
     * 检查必传参数不能为空
     *
     * @param object
     * @param filedNames
     * @return
     */
    public static void checkNull(Object object, String... filedNames) throws BindException {
        List<String> blankList;
        if (Common.isBlank(object)) {
            object = "parameter";
            blankList = Arrays.asList(filedNames.length > 0 ? filedNames : new String[]{"parameter"});
        } else if (object instanceof Map)
            blankList = getMapBlanks((Map) object, filedNames);
        else
            blankList = getBeanBlanks(object, filedNames);
        BindException exception = new BindException(object, "");
        if (blankList.size() > 0) {
            blankList.stream()
                    .map(x -> new ObjectError(x, "checkFailed"))
                    .forEach(exception::addError);
            throw exception;
        }
    }


    /**
     * 检查list中特定字段是否为空
     *
     * @param objects
     * @param filedNames
     */
    public static void checkListNull(List<Object> objects, String... filedNames) throws BindException {
        for (Object object : objects) {
            checkNull(object, filedNames);
        }
    }

    /**
     * 判断参数是否为空
     *
     * @param object
     * @param fieldNames
     * @return
     */
    private static List<String> getBeanBlanks(Object object, String[] fieldNames) {
        return Arrays.stream(fieldNames)
                .filter(val -> Common.isBlank(getValue(object, val)))
                .collect(Collectors.toList());
    }
}
